function varargout = training(varargin)
%  __  __                            _   _       
% |  \/  |                          | | | |      
% | \  / | __ _ _ __ __ _ _   _  ___| |_| |_ ___ 
% | |\/| |/ _` | '__/ _` | | | |/ _ \ __| __/ _ \
% | |  | | (_| | | | (_| | |_| |  __/ |_| ||  __/
% |_|  |_|\__,_|_|  \__, |\__,_|\___|\__|\__\___|
%                      | |                       
%                      |_|                       
%  _    _       _                    _ _         
% | |  | |     (_)                  (_) |        
% | |  | |_ __  ___   _____ _ __ ___ _| |_ _   _ 
% | |  | | '_ \| \ \ / / _ \ '__/ __| | __| | | |
% | |__| | | | | |\ V /  __/ |  \__ \ | |_| |_| |
%  \____/|_| |_|_| \_/ \___|_|  |___/_|\__|\__, |
%                                           __/ |
%                                          |___/ 
% 
% Last Modified by Corey Bost for Marquette University's
% Speech and Signal Processing Lab

%This file is part of the Marquette Univeristy Speech Recognition Toolkit.
%This module will create the HMM definitions from the user data.
%Simply set the values on the sliders or in the edit boxes, choose whether
%or not to include mixtures, and click convert. The inner-workins of the
%code should not be altered unless you really know what you're doing.

%Copyright 2009

% TRAINING M-file for training.fig
%      TRAINING, by itself, creates a new TRAINING or raises the existing
%      singleton*.
%
%      H = TRAINING returns the handle to a new TRAINING or the handle to
%      the existing singleton*.
%
%      TRAINING('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in TRAINING.M with the given input arguments.
%
%      TRAINING('Property','Value',...) creates a new TRAINING or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before training_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to training_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help training

% Last Modified by GUIDE v2.5 11-Aug-2009 16:04:22

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @training_OpeningFcn, ...
                   'gui_OutputFcn',  @training_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before training is made visible.
function training_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to training (see VARARGIN)

global main_dir; 
if isnumeric(main_dir), main_dir = strrep(which('training_OpeningFcn'),'\training.m','');end
% Choose default command line output for training
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
set(gcf,'CloseRequestFcn',@my_closefcn);

% UIWAIT makes training wait for user response (see UIRESUME)
% uiwait(handles.figure1);

%User defined close function
function my_closefcn(hObject, eventdata, handles, varargin)
%Close function
global main_dir;
cd(main_dir);
delete(gcf);
htk_tools

% --- Outputs from this function are returned to the command line.
function varargout = training_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in checkbox1.
function checkbox1_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of checkbox1

%This is for using mixtures, checking the box enables both the slider and
%the edit box so the user can enter values manually or move the slider to
%the desired value.
if get(hObject,'Value')
    set(handles.slider1,'Enable','on');
    set(handles.edit1,'Enable','on');
else
    set(handles.slider1,'Enable','off');
    set(handles.edit1,'Enable','off');
end


function edit1_Callback(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit1 as text
%        str2double(get(hObject,'String')) returns contents of edit1 as a double
if str2double(get(hObject,'String'))>=1 & str2double(get(hObject,'String'))<=8
   set(handles.slider1,'Value', round(str2double(get(hObject,'String'))));
end
set(hObject,'string',round(str2double(get(hObject,'string'))));

% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
set(hObject,'Enable','off');
set(hObject,'String','1');


% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
% hObject    handle to slider1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
set(handles.edit1,'string',round(get(hObject,'value')));

% --- Executes during object creation, after setting all properties.
function slider1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end
set(hObject,'Enable','off');
set(hObject,'SliderStep',[1/7,1/7]);

% --- Executes on button press in train.
function train_Callback(hObject, eventdata, handles)
% hObject    handle to train (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global main_dir;
for index=0:15
    if (exist([main_dir '/Data/HMM' num2str(index) ''],'dir')~=7)
        mkdir([main_dir '/Data'], ['HMM',num2str(index)]);
    end
end
if (exist([main_dir '/Data/Result_allcalltype'],'dir')~=7)
    mkdir([main_dir '/Data/Result_allcalltype']);
end
%These values will be used later
states = round(get(handles.slider2,'value'));
if get(handles.checkbox2,'Value')==1
    cross_val = round(get(handles.slider3,'value'));
else
    cross_val = 1;
end

%Check is used to see if the data has been converted to .mfc yet. If not,
%check is an array with values '.' and '..', so we must look and find out
%if it is larger than two.
check = dir('Data/Data_exp/MFC');
if length(check)>2
    script_files(hObject, eventdata, handles,cross_val);
    mixflag = get(handles.checkbox1,'value');
    type = load_type(hObject, eventdata, handles);
    mix = round(get(handles.slider1,'value'));
    msgbox('Please wait while we train your models!','Training');
    cd('Data')
    run_exp(states, mix, type, mixflag,cross_val)
    cd('..')
    msgbox('Training Complete!','Complete');
else
    h = errordlg('You need to run the Data Preparation before you can train!','Error!');
    uiwait(h);
    delete(gcf);
    data_prepare;
end

function edit2_Callback(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if str2double(get(hObject,'String'))>=2 && str2double(get(hObject,'String'))<=20
   set(handles.slider2,'Value', round(str2double(get(hObject,'String'))));
end
set(handles.edit2,'string', round(str2double(get(handles.edit2,'string'))));
% Hints: get(hObject,'String') returns contents of edit2 as text
%        str2double(get(hObject,'String')) returns contents of edit2 as a double


% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
set(hObject,'string',3);


% --- Executes on slider movement.
function slider2_Callback(hObject, eventdata, handles)
% hObject    handle to slider2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.edit2,'string',round(get(hObject,'value')))
% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider


% --- Executes during object creation, after setting all properties.
function slider2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end
set(hObject,'SliderStep',[1/17,1/17]);
set(hObject,'value',3);
set(hObject,'min', 3);
set(hObject,'Max',20);

function type = load_type(hObject, eventdata, handles)
% hObject    handle to slider2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% config = exist('Data/config.file','file');
global main_dir;
type = 'MFCC_Z_E_D_A'; %Default MFCC_Z_E_D_A
count = 0;
if ~exist([main_dir '/Data/config'],'file')
    msgbox('Please make the config file first!');
else
    %This portion reads the config file to retrieve the conversion type of
    %the data. (e.g. MFCC_E)
    fid = fopen([main_dir '/Data/config']);
    while feof(fid) == 0
        tline = fgetl(fid);
        matches = findstr(tline, 'TARGETKIND');
        num = length(matches);
        if num > 0
            remain = tline;
            while true
                count = count + 1;
                [str, remain] = strtok(remain);
                if isempty(str)
                    break;
                end
                if findstr(str,'MFCC')
                    type = str;
                end
            end
        end
    end
    fclose(fid);
end

function script_files(hObject, eventdata, handles,cross_val)
%This portion of the code writes the batch files to train and test the data
global main_dir;
%This loop extracts the names of the converted files' folder into an array.
file_dir=dir([main_dir '/Data/Data_exp/MFC']);
for i=1:length(file_dir)-2
    calltype{i}=file_dir(i+2).name;
end

num_cross_val=cross_val;
use_cross = get(handles.checkbox2,'value');
%This loops make sure that every file is used for training, but that if a
%file is used for testing, that it does get used during training.
if use_cross ~= 0
    for I=1:num_cross_val
        fid_train=fopen(['Data/train' num2str(I) '.scp'],'w');
        fid_test=fopen(['Data/test' num2str(I) '.scp'],'w');
        for k=1:length(calltype)
            av_files=dir(['Data/Data_exp/MFC/' calltype{k}]);
            test_size=floor(length(av_files)/num_cross_val);
            if I==1
                for j=I*test_size+1:length(av_files)-2
                    fprintf(fid_train,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
                end
                for j=1:I*test_size
                    fprintf(fid_test,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
                end
            else if I==num_cross_val
                    for j=1:(I-1)*test_size
                        fprintf(fid_train,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
                    end
                    for j=(I-1)*test_size+1:length(av_files)-2
                        fprintf(fid_test,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
                    end
                else
                    for j=1:(I-1)*test_size
                        fprintf(fid_train,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
                    end
                    for j=I*test_size+1:length(av_files)-2
                        fprintf(fid_train,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
                    end
                    for j=(I-1)*test_size+1:I*test_size
                        fprintf(fid_test,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
                    end
                end
            end
        end
        status=fclose(fid_train);
        status=fclose(fid_test);
    end
else
    fid_train=fopen(['Data/train' num2str(1) '.scp'],'w');
    fid_test=fopen(['Data/test' num2str(1) '.scp'],'w');
    for k=1:length(calltype)
        av_files=dir(['Data/Data_exp/MFC/' calltype{k}]);
        for j = 1:length(av_files)-2
            fprintf(fid_train,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
            fprintf(fid_test,['"Data_exp/MFC/' calltype{k} '/' av_files(j+2).name '"\n']);
        end
    end
    fclose(fid_train);
    fclose(fid_test);
end


% --------------------------------------------------------------------
function file_menu_Callback(hObject, eventdata, handles)
% hObject    handle to file_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function help_Callback(hObject, eventdata, handles)
% hObject    handle to help (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function exit_Callback(hObject, eventdata, handles)
% hObject    handle to exit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
my_closefcn(hObject,eventdata,handles)


% --------------------------------------------------------------------
function module_help_Callback(hObject, eventdata, handles)
% hObject    handle to module_help (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%{
helpdlg(sprintf(['Increasing the number of states will increase the'...
    ' accuracy of the trained models.\n\nIncluding mixtures will'...
    ' also greatly increase accuracy, but will also increase the '...
    'time needed for training.']));
%}
help_launch('train');

% --------------------------------------------------------------------
function about_us_Callback(hObject, eventdata, handles)
% hObject    handle to about_us (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
about_us



function edit3_Callback(hObject, eventdata, handles)
% hObject    handle to edit3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit3 as text
%        str2double(get(hObject,'String')) returns contents of edit3 as a double
if str2double(get(hObject,'String'))>=2 & str2double(get(hObject,'String'))<=10
   set(handles.slider3,'Value', round(str2double(get(hObject,'String'))));
end
set(handles.slider3,'string', round(str2double(get(handles.edit3,'string'))));
set(hObject,'string', round(str2double(get(handles.edit3,'string'))));

% --- Executes during object creation, after setting all properties.
function edit3_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on slider movement.
function slider3_Callback(hObject, eventdata, handles)
% hObject    handle to slider3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
set(handles.edit3,'string',round(get(hObject,'value')))

% --- Executes during object creation, after setting all properties.
function slider3_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end
set(hObject,'SliderStep',[1/8,1/8]);
set(hObject,'value',5);
set(hObject,'MAX',10);
set(hObject,'MIN',2);


% --- Executes on button press in checkbox2.
function checkbox2_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox2
if get(hObject,'Value')
    set(handles.slider3,'enable','on')
    set(handles.edit3,'enable','on')
else
    set(handles.slider3,'enable','off')
    set(handles.edit3,'enable','off')
end
